package com.gzsxy.esjy.gateway.sso;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.gzsxy.esjy.common.base.exception.impl.CustomAssert;
import com.gzsxy.esjy.common.base.result.R;
import com.gzsxy.esjy.gateway.sso.dto.BaseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;

/**
 * @author xiaolong
 * @version 1.0
 * @description: Sso封装RestTemple
 * @date 2021/11/15 14:57
 */
@Configuration
public class SsoRestTemple {


    private final RestTemplate restTemplate;

    @Autowired
    private RestTemplate balanceRestTemplate;


    public SsoRestTemple(){
        this.restTemplate = getRestTemplate();
    }


    /**
     * @description: Get请求封装
     * @param
     * @return
     */
    public <R extends BaseResult> R get(String url,Class<R> result, String realIp){
        RestTemplate restClient  = restTemplate;
        if (url.startsWith("lb")){
            restClient = balanceRestTemplate;
            url = "http"+url.substring(2);
        }
        HttpHeaders headers = new HttpHeaders();
        //获取项目地址真实ip
        headers.add("X-Forwarded-For",realIp);
        HttpEntity<String> requestE = new HttpEntity<>(null, headers);
        ResponseEntity<R> exchange = restClient.exchange(url, HttpMethod.GET, requestE, result);
        R body = exchange.getBody();
        CustomAssert.notTrue(body.getCode() == 200 || body.getCode() == 0 ,body.getMsg(),body.getCode());
        CustomAssert.notTrue(body.isSuccess(),body.getMsg(),body.getCode());
        return body;
    }


    /**
     * @description: 根据token获取资源文件列表
     * @param
     * @return
     */
    public <T extends BaseResult,R> List<R> getListByToken(String url,String token,Class<T> responseClazz,Class<R> result){
        CustomAssert.notBlank(token,"access_token不存在",403);
        RestTemplate restClient = restTemplate;
        if (url.startsWith("lb")){
            restClient = balanceRestTemplate;
            url = "http"+url.substring(2);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization","Bearer "+token);
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> requestE = new HttpEntity<>(null, headers);
        ResponseEntity<T> exchange = restClient.exchange(url, HttpMethod.GET, requestE, responseClazz);
        T body = exchange.getBody();
        CustomAssert.notTrue(body != null && body.getCode() == 200,body == null?"Sso连接异常":body.getMsg(),body.getCode());
        return body.getData();
    }


    /**
     * @description: Post请求封装
     * @param
     * @return
     */
    public <T extends BaseResult> T post(String url, String token, Class<T> responseClazz, String bodyJson){
        CustomAssert.notBlank(token,"access_token不存在",403);
        RestTemplate restClient = restTemplate;
        if (url.startsWith("lb")){
            restClient = balanceRestTemplate;
            url = "http"+url.substring(2);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization","Bearer"+token);
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> requestE = new HttpEntity<>(bodyJson, headers);
        ResponseEntity<T> exchange = restClient.exchange(url, HttpMethod.POST, requestE, responseClazz);
        T body = exchange.getBody();
        CustomAssert.notTrue(body != null && body.getCode() == 200,body == null?"Sso连接异常":body.getMsg(),body.getCode());
        return body;
    }



    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return getRestTemplate();
    }


    private RestTemplate getRestTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        //换上fastjson
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
        while (iterator.hasNext()){
            HttpMessageConverter<?> converter = iterator.next();
            //原有的String是ISO-8859-1编码 去掉
            if (converter instanceof StringHttpMessageConverter){
                iterator.remove();
            }
            //由于系统中默认有jackson 在转换json时自动会启用 但是我们不想使用它 可以直接移除
            if (converter instanceof GsonHttpMessageConverter || converter instanceof MappingJackson2HttpMessageConverter){
                iterator.remove();
            }

        }
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.DisableCircularReferenceDetect);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        messageConverters.add(fastJsonHttpMessageConverter);
        return restTemplate;
    }
}
